package ac.svn.accesscontrol.ui.helper;

import java.awt.Component;
import java.util.HashSet;
import java.util.Set;

import javax.swing.Icon;
import javax.swing.JLabel;

import ac.svn.accesscontrol.manager.SVNInfoManager;
import ac.svn.accesscontrol.store.AccessUnit;
import ac.svn.accesscontrol.store.ISVNItem;
import ac.svn.accesscontrol.store.SVNGroup;
import ac.svn.accesscontrol.store.SVNLocation;
import ac.svn.accesscontrol.store.SVNUser;
import ac.svn.accesscontrol.ui.UIComponentLibrary;
import ac.svn.accesscontrol.ui.XTextPane;
import ac.svn.accesscontrol.utils.Utility;

public class AccessRightsLister implements XTextPane.IStyles 
{
	private boolean clearRequired 	= false;
	private boolean group 		= false;
	private String targetId		= null;
	private SVNInfoManager infoManager  = null;
	private Thread listerThread		= null;
	private XTextPane textPane		= null;
	private JLabel membershipLabel	= null;

	public AccessRightsLister(String componentId)
	{
		textPane = (XTextPane) UIComponentLibrary.getComponent(componentId);
		initLister();
	}

	public AccessRightsLister(Component component)
	{
		textPane = (XTextPane) component;
		initLister();
	}

	private void initLister()
	{
		infoManager	 		= SVNInfoManager.getInfoManager();

		listerThread = new Thread(new Runnable() {
			@Override
			public void run() {
				if(isClearRequired())
				{
					textPane.setText(null);
				}


				if(isGroup())
				{
					SVNGroup group = infoManager.getGroup(targetId);
					textPane.addText("Listing for Group: " , STYLE_HEADING);
					textPane.addTextWithLine(group.getGroupName(), STYLE_GROUP);
					textPane.addTextWithLine("Members:",STYLE_DEF);

					int count = 0;
					for(String userId : group.getGroupMembers())
					{
						SVNUser svnUser = SVNInfoManager.getInfoManager().getSvnUser(userId);
						textPane.addText((String.valueOf(++count)) + ". ", STYLE_DEF);
						textPane.addTextWithLine(String.format("%s [%s]",svnUser.getUserName(),svnUser.getUserAlias()),STYLE_USER);
					}
					textPane.addTextWithLine("\n\n",STYLE_DEF);
					textPane.addText("Locations accessible to ",STYLE_HEADING);
					textPane.addTextWithLine(group.getGroupName(), STYLE_GROUP);
				}
				else
				{
					SVNUser user = infoManager.getSvnUser(targetId);
					textPane.addText("Listing for User: " , XTextPane.IStyles.STYLE_HEADING);
					textPane.addTextWithLine(user.getUserName(), STYLE_USER);
					textPane.addTextWithLine("Groups:",STYLE_DEF);

					int count = 0;
					for(String groupId : user.getGroups())
					{
						SVNGroup group = SVNInfoManager.getInfoManager().getGroup(groupId);
						textPane.addText((String.valueOf(++count)) + ". ", STYLE_DEF);
						textPane.addTextWithLine(String.format("%s [%s]",group.getGroupName(),group.getGroupAlias()),STYLE_GROUP);
					}

					textPane.addTextWithLine("\n\n",STYLE_DEF);
					textPane.addText("Locations accessible to ",STYLE_HEADING);
					textPane.addTextWithLine(user.getUserName(), STYLE_USER);
				}

				//Find out membership set.
				Set<String> membershipSet = new HashSet<String>();
				membershipSet.add(targetId.trim());
				if(!isGroup())
				{
					SVNUser user = infoManager.getSvnUser(targetId);
					for(String member : user.getGroups())
					{
						membershipSet.add(member.trim());
					}
				}

				int count = 0;
				for(ISVNItem loc: infoManager.getAllLocations())
				{
					SVNLocation location = (SVNLocation) loc;
					//System.err.println(location.getLocationPath());
					Set<String> accessUnits = location.getAccessUnits();
					for(String accessUnitId : accessUnits)
					{
						AccessUnit accessUnit = infoManager.getAccessUnit(accessUnitId);
						if(membershipSet.contains(accessUnit.getOwnerId().trim()))
						{	
							addLocationToText(accessUnit, ++count);
						}
					}
				}

				if(isGroup())
				{
					SVNGroup grp = infoManager.getGroup(targetId);
					String text  = String.format("Group: %s[as %s] members of group %s",grp.getGroupName(),grp.getGroupAlias(),grp.getGroupMembers());
					showStatusText(text);
				}
				else
				{
					SVNUser user = infoManager.getSvnUser(targetId);
					String text = String.format("%s[%s] member of groups %s .",user.getUserName(),user.getUserAlias(),user.getGroups());
					showStatusText(text);
				}
				textPane.addTextWithLine("\nListing Complete!", STYLE_HEADING);
			}
		});
	}

	private void addLocationToText(AccessUnit accessUnit, int count)
	{

		String acc = "";
		if(accessUnit.isReadEnabled())
		{
			acc+="R";
		}
		else
		{
			acc+="";
		}

		if(accessUnit.isWriteEnabled())
		{
			acc+="W";
		}
		else
		{
			acc+="";
		}

		Icon icon ;// = new ImageIcon(Utility.getImage("images/read.png"));
		if("R".equals(acc))
		{
			icon = Utility.getImageIcon("images/read.png");
		}
		else if(acc.contains("W"))
		{
			icon = Utility.getImageIcon("images/readWrite.png");
		}
		else
		{
			icon = Utility.getImageIcon("images/none.png");
		}


		//textPane.addText(((String.valueOf(count) + ". ") + acc),STYLE_ACCESS);
		textPane.insertIcon(icon);
		textPane.addTextWithLine(accessUnit.getLocationPath(), STYLE_LOC);
	}

	public void listAccessRights(String userId)
	{
		this.targetId = null;
		this.targetId = userId;

		if(listerThread.isAlive())
		{
			listerThread.interrupt();
		}
		listerThread.run();
	}

	public boolean isClearRequired() {
		return clearRequired;
	}

	public void setClearRequired(boolean clearRequired) {
		this.clearRequired = clearRequired;
	}

	public boolean isGroup() {
		return group;
	}

	public void setGroup(boolean group) {
		this.group = group;
	}


	public void showStatusText(String text){
		if(null != membershipLabel)
		{
			membershipLabel.setText(text);
		}
	}

	/**
	 * @return the membershipLabel
	 */
	public JLabel getMembershipLabel() {
		return membershipLabel;
	}

	/**
	 * @param membershipLabel the membershipLabel to set
	 */
	public void setMembershipLabel(JLabel membershipLabel) {
		this.membershipLabel = membershipLabel;
	}

}
